package com.cnhis.onehis;

import java.io.IOException;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Callable;
import java.util.concurrent.FutureTask;

import org.apache.ibatis.session.SqlSession;
import org.apache.log4j.Logger;
import org.apache.zookeeper.common.PathUtils;
import org.jdom.Document;
import org.jdom.Element;
import org.jdom.JDOMException;
import org.jdom.input.SAXBuilder;

import com.alibaba.fastjson.JSON;
import com.cnhis.cloudhealth.clinical.clidoctor.clinewadvice.bo.CliNewAdviceBo;
import com.cnhis.cloudhealth.clinical.util.AsyncUtil;
import com.cnhis.cloudhealth.clinical.util.ExUtil;
import com.cnhis.cloudhealth.clinical.util.Logutil;
import com.cnhis.cloudhealth.clinical.util.SerializeUtil_prjcli;
import com.cnhis.cloudhealth.clinical.util.cache.MybatisCacheWzGuava;
import com.cnhis.cloudhealth.clinical.util.cache.MybatisRedisCache;
import com.cnhis.onehis.util.DbUtil;
import com.google.common.collect.Maps;
import com.mchange.v1.db.sql.ResultSetUtils;

public class MybatisUtil {
	public static Logger lgr = Logger.getLogger(MybatisUtil.class);

	public MybatisUtil(String cfg2) {
		this.cfg = cfg2;
	}

	public MybatisUtil() {
		// TODO Auto-generated constructor stub
	}

	public static void main(String[] args) throws SQLException {
		System.out.println("");
		String sqlid = "adviceSousuo_kucui";
		  String cfg = "C:\\0wkspc\\clinical\\src\\main\\java\\com\\cnhis\\cloudhealth\\clinical\\clidoctor\\clischemedefine\\mapper\\CliSchemeDefineMapper.xml";
		cfg = "C:\\0wkspc\\clinical\\src\\main\\java\\com\\cnhis\\cloudhealth\\clinical\\clidoctor\\lucence\\mapper\\lucenceMapper.xml";
	/*
	 *      \\\\C:\0wkspc\clis413\clinical\src\main\resources\META-INF\mybatis\mybatis-config4upstock.xml
	 * */
		final	String cfg1 = "C:\\0wkspc\\clis413\\clinical\\src\\main\\resources\\META-INF\\mybatis\\mybatis-config4upstock.xml";
		//SqlSession ss = MybatisUtil.getSqlSession(cfg);
		
		for(int i=0;i<1;i++)
		{
			long l1=System.currentTimeMillis();
		
			AsyncUtil.execMeth_Async(new FutureTask<>(new Callable () {

				@Override
				public Object call() throws Exception {
					testMybatisCache(cfg1);
					System.out.println("---------MybatisCacheWzGuava.Cache1_guava：："+MybatisCacheWzGuava.Cache1_guava.asMap()); 
					
					return null;
				}
			}), "threadName");
			
			
			long l2=System.currentTimeMillis();
			System.out.println( "use timed:"+(l2-l2));
		}
	
	 

		// testmultisql(ss);
		// System.out.println(JSON.toJSONString(li));
		// String s = getMybaticsCfgedSqlBysqlid(cfg, "queryDoctorAdviceList1");

		// t1(s);
		//  insertCviCBMTest(cfg);
		// exec("CliNewAdvice.insertCviCBM",
		// "C:\\0log\\insertCviCbmParamMap2018-04-10 17_12_11_717.map");

		  
		  //test   max prkcol val
//		MybatisUtil mybatisUtil = new MybatisUtil(cfg);
//	long startPrkColLong=	mybatisUtil.getMaxLong("cbm1", "cbm01");
//	System.out.println(startPrkColLong);
		// new MybatisUtil().insertCviCBMTest2(cfg);

		// MybatisUtil.insertCviCBMTest(cfg);
		System.out.println("--f");

	}

	private static void testMybatisCache(String cfg) {
		HashMap map = new HashMap();
		Object productId=9999;
		map.put("productId", productId);
		Object programId=9999;
		map.put("programId", programId);
		Object paramNo=12;
		map.put("paramNo", paramNo);
		SqlSession ss = MybatisUtil.getSqlSessionNew(cfg);
		lgr.info("$$$$$$$$$$$$ SqlSession id " + ss.toString());
		MybatisUtil MybatisUtil1 = new MybatisUtil();
	  Object rzt= ss.selectOne("CliSendAdvice.getParameter", map);
	  ss.close();
	    System.out.println(rzt);
	}

	
	public long getMaxLong(SqlSession ss ,String tab, String prkCol) {
	//	SqlSession ss = MybatisUtil.getSqlSession(cfg);
		Connection conn = ss.getConnection();
		Statement Statement1 = getStt(conn);
		long startTime = System.currentTimeMillis();
		try {
			String sql = "select  max(" + prkCol + ") as id from " + tab;
			System.out.println(sql);
			ResultSet rs1 = Statement1.executeQuery(sql);
			List<Map> li = DbUtil.rs2List(rs1);
			if(li.size()==0) //empty tab
				return 1;
			Map map = li.get(0);
			
			return Long.parseLong(map.get("id").toString());
		} catch (SQLException e) {
			ExUtil.throwExV2(e);
		}
		return -1;

	}
	
	
	public long getMaxLong(String tab, String prkCol) {
		SqlSession ss = MybatisUtil.getSqlSession(cfg);
		Connection conn = ss.getConnection();
		Statement Statement1 = getStt(conn);
		long startTime = System.currentTimeMillis();
		try {
			String sql = "select  max(" + prkCol + ") as id from " + tab;
			System.out.println(sql);
			ResultSet rs1 = Statement1.executeQuery(sql);
			List<Map> li = DbUtil.rs2List(rs1);
			if(li.size()==0) //empty tab
				return 1;
			Map map = li.get(0);
			
			return Long.parseLong(map.get("id").toString());
		} catch (SQLException e) {
			ExUtil.throwExV2(e);
		}
		return -1;

	}

	private Statement getStt(Connection conn2) {
		Statement st = null;
		try {
			// conn.setAutoCommit(true);
			st = conn2.createStatement();
		} catch (SQLException e1) {
			ExUtil.throwExV2(e1);
		}

		return st;
	}

	private long nowAutoId = 0;

	/**
	 * insertCviCBM2
	 * 
	 * @param cfg
	 */
	public void insertCviCBMTest2(String cfg) {
		MybatisUtil mc = new MybatisUtil();
		mc.ini(cfg);
		Map m = (Map) SerializeUtil_prjcli
				.serizGetObjFromFile("C:\\0log\\insertCviCbmParamMap2018-04-10 17_12_11_717.map");
		List li = (List) m.get("tmpCBM");
		Map tmpCBM = (Map) li.get(0);

		for (int i = 0; i < 3; i++) {
			long l = System.currentTimeMillis();

			// long cmb01 = (long) tmpCBM.get("cbm01");
			long cmb01 = newId();
			tmpCBM.put("cbm01", cmb01);
			setNowId(cmb01);
			SqlSession ss = MybatisUtil.getSqlSession(cfg);
			lgr.info("$$$$$$$$$$$$ SqlSession id " + ss.toString());
			mc.insert("CliNewAdvice.insertCviCBM2", m, ss);
			ss.commit();
			Logutil.infoTime(lgr, "insertCviCBMTest", l);

		}
		SqlSession ss = MybatisUtil.getSqlSession(cfg);
		ss.close();
	}

	private void setNowId(long cmb01) {
		this.nowAutoId = cmb01;

	}

	private long newId() {
		// TODO Auto-generated method stub
		return nowmax() + 1;
	}

	private long nowmax() {
		if (this.nowAutoId != 0)
			return this.nowAutoId;
		else
			return 5;
	}

	/**
	 * insertCviCBM2
	 * 
	 * @param cfg
	 */
	public static void insertCviCBMTest(String cfg) {
		MybatisUtil mybatisUtil = new MybatisUtil();
		mybatisUtil.ini(cfg);
		MybatisUtil.getSqlSession(cfg);
		String fullMap = "C:\\0log\\insertCviCbmParamMap2018-04-10 17_12_11_717.map";
		Map m = (Map) SerializeUtil_prjcli
				.serizGetObjFromFile(fullMap);
		List li = (List) m.get("tmpCBM");
		Map tmpCBM = (Map) li.get(0);
		 
		long startPrkColLong=	mybatisUtil.getMaxLong("cbm1", "cbm01");
		for (int i = 0; i < 3; i++) {
			long l = System.currentTimeMillis();
            
			long cmb01_new=newNextid(startPrkColLong,1);
			tmpCBM.put("cbm01", cmb01_new);
			mybatisUtil.setNowId(cmb01_new);
			startPrkColLong=cmb01_new;
			mybatisUtil.insert("CliNewAdvice.insertCviCBM", m);
			Logutil.infoTime(lgr, "insertCviCBMTest", l);

		}
		
		mybatisUtil.commit();
	}

	private void commit() {
		 
		MybatisUtil.getSqlSession(cfg).commit();
	}

	private static long newNextid(long startPrkColLong, int i_step) {
	 
		return startPrkColLong+i_step;
	}

	private String cfg;

	private void ini(String cfg) {
		this.cfg = cfg;
		MybatisUtil.getSqlSession(cfg);

	}

	private void insert(String sqlid, Map m, SqlSession ss) {
		// SqlSession ss = MybatisUtil.getSqlSession(this.cfg);
		ss.insert(sqlid, m);

	}

	private void insert(String sqlid, Map m) {
		SqlSession ss = MybatisUtil.getSqlSession(this.cfg);
		ss.insert(sqlid, m);

	}

	private static void exec(String sqlid, String mapObjPath) {

	}

	public static void testmultisql(SqlSession ss) {
		// testMultiInset(ss);

		// test list
		Map map = Maps.newConcurrentMap();
		map.put("tablename", "2018_04_09__19_01_30_050");
		List<Map> li_VAF2 = ss.selectList("HosSendAdvice.updateVAF2_VBI2_v2s49_select_VAF2_byTmpVAFzt", map);
		// update vaf2
		for (Map map_vaf2 : li_VAF2) {
			map_vaf2.put("VAF10", 8);
		}
	}

	public static void testMultiInset(SqlSession ss) {
		// test insert multi sql
		Map map = (Map) SerializeUtil_prjcli
				.serizGetObjFromFile("C:\\0logs\\updateVAF2_VBI2_pramMap2018-04-09 18_52_03_639.txt");
		map.put("tablename", "2018_04_09__19_01_30_050");
		System.out.println(JSON.toJSONString(map));
		int rztCnt = ss.insert("HosSendAdvice.ins_Tmp_VAFzt_v2s49_inst_multi", map);
		System.out.println(rztCnt);
	}

	public static void t1(String s) throws SQLException {

		Map m = Maps.newHashMap();
		m.put("corporationid", -5);
		m.put("bck01", 1);
		m.put("yiyuanid", 1);

		String trueSql = getTrueSql(s, m);
		System.out.println(trueSql);

		Statement Statement1 = getStt();
		long startTime = System.currentTimeMillis();
		ResultSet rs1 = Statement1.executeQuery(trueSql);
		long endTime = System.currentTimeMillis();
		long excTime = (long) (endTime - startTime);
		System.out.println(excTime);
		// String
		// f="D:\\0workspace\\atiplat_restapi\\src\\aaaPKg\\flow_design_cs.xml";
		//
		// Map m=(Map)
		// serilizeUtil.serizGetObjFromFile("c:\\logs\\adviceSousuo_kucui_map_8080f6ab-35b1-440f-b1b5-8c1b0ea2de32");
		//
		// Statement st = getStt(); // ini envi
		//
		// List li= getSqlSession().selectList(sqlid, m);
		// System.out.println(li.size());
	}

	Connection conn;

	public Connection get_conn() {

		SqlSession session = getSqlSession();
		conn = session.getConnection();
		return conn;

	}

	protected static Statement getStt() {

		SqlSession session = getSqlSession();
		Connection conn = session.getConnection();

		Statement st = null;
		try {
			conn.setAutoCommit(true);
			st = conn.createStatement();
		} catch (SQLException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}

		return st;
	}

	private static SqlSession getSqlSession() {
		MybatisSessionFactory.CONFIG_FILE_LOCATION = "/com/attilax/db/mybatisutil/mybatis_postgresql.xml";
		SqlSession session = MybatisSessionFactory.getSession();
		return session;
	}

	public static SqlSession getSqlSession(String CONFIG_FILE_LOCATION) {
		MybatisSessionFactory.CONFIG_FILE_LOCATION = CONFIG_FILE_LOCATION;
		SqlSession session = MybatisSessionFactory.getSession();
		return session;
	}
	

	public static SqlSession getSqlSessionNew(String CONFIG_FILE_LOCATION) {
		MybatisSessionFactory.CONFIG_FILE_LOCATION = CONFIG_FILE_LOCATION;
		MybatisSessionFactory.ini_once();
	     
		if (MybatisSessionFactory.sessionFactory == null) {
			MybatisSessionFactory.rebuildSessionFactory();
		}
		SqlSession	session = MybatisSessionFactory. sessionFactory.openSession();
			
		 return session;
	}
	
	@Deprecated
    public static SqlSession getSqlSessionNew()  {
    	
    	MybatisSessionFactory.ini_once();
     
			if (MybatisSessionFactory.sessionFactory == null) {
				MybatisSessionFactory.rebuildSessionFactory();
			}
			SqlSession	session = MybatisSessionFactory. sessionFactory.openSession();
				
			 return session;
	 
    }

	private static String getTrueSql(String sql, Map<String, Object> m) {
		for (Map.Entry entry : m.entrySet()) {
			String key = (String) entry.getKey();
			key = key.trim();
			System.out.println(key + ":" + entry.getValue());

			sql = sql.replaceAll("\\#\\{" + key + "\\}", getValueByTypeinSql(entry.getValue()));
		}
		return sql;
	}

	private static String getValueByTypeinSql(Object value) {
		if (value.getClass() == String.class)
			return "'" + value.toString() + "'";
		if (value.getClass() == Integer.class)
			return value.toString();
		throw new RuntimeException("getValueByTypeinSql:: value not jude type");
	}

	private static String getMybaticsCfgedSqlBysqlid(String f, String sqlid) {
		// TODO Auto-generated method stub

		SAXBuilder builder = new SAXBuilder(false);

		Document doc;
		try {
			doc = builder.build(f);
		} catch (JDOMException | IOException e) {
			throw new RuntimeException(e);
		}

		Element books = doc.getRootElement();

		List<Element> definitions_eles = books.getChildren("select");
		for (Element e : definitions_eles) {
			System.out.println(e.getAttribute("id"));
			if (e.getAttribute("id").getValue().equals(sqlid))
				return e.getText();
		}

		// Element process_ele=books.getChild("process");

		// System.out.println(process_ele.getAttributeValue("deadlineLimit"));

		System.out.println("--f");
		return sqlid;

	}

}
